package com.itheima.logdemo.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * filter拦截请求
 * 无论直接发起的请求，还是微服务之间的调用，都会经过filter
 * 生成logbean，并在threadlocal中传递，保障jvm内的上下文保持
 */
@Configuration
@Order(1)
@WebFilter(filterName = "logFilter", urlPatterns = "/*")
public class LogFilter implements Filter {
    
    @Value("${spring.application.name}")
    String appName;
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        
        //sid，取cookie，用户登陆后会设置
        String cookieVal = null;
        Cookie[] cookies = httpServletRequest.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("sid".equals(cookie.getName())) {
                    cookieVal = cookie.getValue();
                    break;
                }
            }
        }
        
        //rid，tid，sid，先从header头获取
        //如果没有，那就说明是web模块的，直接生成
        String rid = StringUtils.defaultIfBlank(httpServletRequest.getHeader("rid"),
                CommonUtils.getRandomStr(10));
        
        String tid = StringUtils.defaultIfBlank(httpServletRequest.getHeader("tid"),
                CommonUtils.getDevice(httpServletRequest.getHeader("User-Agent")));
        
        String sid = StringUtils.defaultString(httpServletRequest.getHeader("sid"), cookieVal);
        
        String url = httpServletRequest.getRequestURI();
        
        //创建LogBean对象，装载上面的信息
        LogBean logBean = new LogBean(rid, sid, tid);
        logBean.setFrom(appName);
        logBean.setUrl(url);
        
        //扔到ThreadLocal里
        LogUtil.setLocalInstance(logBean);
        //打一条信息，表示进入filter了！
        LogUtil.log("I am filter");
        
        chain.doFilter(request, response);
        
        //请求结束后，释放ThreadLocal是一个好习惯！
        LogUtil.removeLocalInstance();
    }
    
}
